package org.activemonitoring.monitors;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.activemonitoring.harvesters.Harvester;
import org.activemonitoring.harvesters.MeasureBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@Configurable
// TODO Exposes on JMX
public class MonitoringServletFilter implements Filter {

    @Autowired
    private Harvester harvester;
    private String moduleName;
    private boolean enable = true;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.moduleName = filterConfig.getServletContext().getContextPath();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        if (this.enable == false) {
            chain.doFilter(request, response);
            return;
        }
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        MeasureBuilder measure = this.harvester.start(this.moduleName, httpRequest.getRequestURI());
        try {
            chain.doFilter(request, response);
        } catch (IOException e) {
            measure.error();
            throw e;
        } catch (ServletException e) {
            measure.error();
            throw e;
            // } catch (org.apache.cxf.interceptor.Fault f) {
            // measure.error();
            // throw (RuntimeException) f;
        } catch (RuntimeException e) {
            measure.error();
            throw e;
        } finally {
            measure.stop();
        }
    }

    @Override
    public void destroy() {
    }

    public void setHarvester(Harvester harvester) {
        this.harvester = harvester;
    }

    public boolean isEnable() {
        return this.enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }
}
